home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 21
/
CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso
/
CUCD
/
Programming
/
Python-1.4
/
Python1.4_Source
/
Modules
/
doslibmodule.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-31
|
16KB
|
693 lines
/********************************************************************
Lowlevel Amiga dos.library module.
-----------------------------------------------
©1996,1997 by Irmen de Jong.
History:
9-jun-96 Created.
13-jun-96 Added WaitSignal().
17-nov-96 Fixed empty template handling.
31-dec-96 Changed CheckSignal to look like WaitSignal.
Module members:
error -- Exeption string object. ('doslib.error')
ReadArgs -- dos.library/ReadArgs function.
result=doslib.ReadArgs(template,args,types)
WaitSignal -- generic Wait() function, like select. Waits for certain
signals to occur.
(sigs,objlist) = WaitSignal(args)
args = integer, object, or list of ints/objects.
integers are sigmask values. Objects must have 'signal'
attribute to get this value.
CheckSignal -- Like Wait() but DOES NOT WAIT FOR THE SIGNALS:
merely checks if certain signals are set.
CompareDates, DateStamp, DateToStr, StrToDate, Fault,
IoErr, SetIoErr, IsFileSystem, Relabel, SetProtection,
SetComment, Examine: just like the original dos.library calls.
DS2time -- convert DateStamp tuple to time() value (see time module)
time2DS -- convert time() value to DateStamp tuple (see time module)
**************************************************************************/
#include <stdlib.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/datetime.h>
#include <dos/rdargs.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include "allobjects.h"
#include "modsupport.h"
static PyObject *error; // Exception
/* Convenience; sets error with IoError() string, return NULL */
/* If ok, return Py_NONE */
static PyObject *check_ok(BOOL ok)
{
char buf[100];
if(ok)
{
Py_INCREF(Py_None);
return Py_None;
}
Fault(IoErr(),NULL,buf,100);
PyErr_SetString(error,buf);
return NULL;
}
/************** MODULE FUNCTIONS *******************/
static PyObject *
Doslib_ReadArgs(PyObject *self, PyObject *arg)
{
char *template;
char *args;
PyObject *types; // the keywords & their types (tuple of tuples)
PyObject *result=NULL;
LONG *argarray;
int num_args;
BOOL free_args=FALSE;
if (!PyArg_ParseTuple(arg, "ssO!", &template, &args,
&PyTuple_Type,&types))
return NULL;
if(PyTuple_Size(types)>0 || strlen(template)>0)
{
/* check argument count */
char *t=template;
num_args=1;
while(*t)
{
if(*t++ == ',') num_args++;
}
if(num_args!=PyTuple_Size(types))
{
PyErr_SetString(ValueError,"types length does not match template");
return NULL;
}
}
else
{
/* template is empty string; no arguments expected */
if(strlen(stpblk(args))>0)
{
SetIoErr(ERROR_TOO_MANY_ARGS);
return check_ok(FALSE);
}
return PyDict_New(); // empty result dictionary
}
if(argarray=calloc(sizeof(LONG),num_args))
{
struct RDArgs *rdargs;
int arglen=strlen(args);
if((arglen==0) || (args[arglen-1]!='\n'))
{
char *t = malloc(arglen+2);
if(t)
{
strcpy(t,args); t[arglen++]='\n'; t[arglen]=0; // add \n !!!
args=t; free_args=TRUE;
}
else
{
free(argarray);
return PyErr_NoMemory();
}
}
if(rdargs = AllocDosObject(DOS_RDARGS, NULL))
{
rdargs->RDA_Flags = RDAF_NOPROMPT;
rdargs->RDA_Source.CS_Buffer = args;
rdargs->RDA_Source.CS_Length = arglen;
rdargs->RDA_Source.CS_CurChr = 0;
rdargs->RDA_DAList = NULL;
rdargs->RDA_Buffer = NULL;
if( !ReadArgs(template, argarray, rdargs) )
{
(void)check_ok(FALSE);
}
else
{
if(result=PyDict_New())
{
/************
Traverse the types tuple and for each argument,
extract it's value. types consists of tuples (k,t) where:
k=keyword;
t=the keyword's type:
'X' - string
'S','T' - bool (integer) !!! T not yet supported
'N' - integer
'A' - array of strings
'I' - array of ints
***********/
PyObject *tup, *val;
BOOL result_ok=TRUE;
int cnt=0;
while (result_ok && (tup=PyTuple_GetItem(types, cnt)))
{
PyObject *keyword, *type;
char *type_c;
if(PyTuple_Size(tup)!=2)
{
PyErr_SetString(ValueError,"types tuple invalid");
result_ok=FALSE; break;
}
keyword=PyTuple_GetItem(tup,0);
type=PyTuple_GetItem(tup,1);
result_ok=FALSE;
type_c=PyString_AsString(type);
if(type_c==NULL)
{
result_ok=FALSE; break; /* no string!? */
}
switch (type_c[0]) {
case 'S': // boolean switch
if(val=PyInt_FromLong(argarray[cnt]))
{
result_ok=(0==PyDict_SetItem(result,keyword,val));
Py_DECREF(val);
}
break;
case 'N': // number
if(argarray[cnt])
{
if(val=PyInt_FromLong(*(LONG*)argarray[cnt]))
{
result_ok=(0==PyDict_SetItem(result,keyword,val));
Py_DECREF(val);
}
}
else result_ok=(0==PyDict_SetItem(result,keyword,Py_None));
break;
case 'X': // string
if(argarray[cnt])
{
if(val=PyString_FromString((STRPTR)argarray[cnt]))
{
result_ok=(0==PyDict_SetItem(result,keyword,val));
Py_DECREF(val);
}
}
else result_ok=(0==PyDict_SetItem(result,keyword,Py_None));
break;
case 'A': // array of strings
case 'I': // array of numbers
if(val=PyList_New(0))
{
if(argarray[cnt])
{
if(type_c[0]=='A')
{
char **str = (char**)argarray[cnt];
PyObject *so;
/* build the string list */
while(*str)
{
if(so=PyString_FromString(*str))
{
if(!(result_ok=(0==PyList_Append(val,so))))
break;
Py_DECREF(so);
}
else break;
str++;
}
}
else /* array of numbers */
{
int **ia = (int**)argarray[cnt];
PyObject *io;
/* build the integer list */
while(*ia)
{
if(io=PyInt_FromLong(**ia))
{
if(!(result_ok=(0==PyList_Append(val,io))))
break;
Py_DECREF(io);
}
else break;
ia++;
}
}
result_ok=result_ok&&(0==PyDict_SetItem(result,keyword,val));
}
else
{
// insert the empty list.
result_ok=(0==PyDict_SetItem(result,keyword,val));
}
Py_DECREF(val);
}
break;
default:
PyErr_SetString(ValueError,"illegal arg type");
break;
}
cnt++;
}
if(!result_ok)
{
Py_DECREF(result);
result=0;
}
}
}
FreeArgs(rdargs);
FreeDosObject( DOS_RDARGS, rdargs );
}
else (void)PyErr_NoMemory();
if(free_args) free(args);
free(argarray);
}
else (void)PyErr_NoMemory();
return (PyObject*)result;
}
static PyObject *
CheckOrWaitSignal(PyObject *self, PyObject *arg, BOOL doWait)
{
struct {
PyObject *ob; // the object, NULL means: only sigmask value
ULONG sigmask;
} objs[32];
int i,listsize = 0;
PyObject *argo, *result;
ULONG signal;
if(!PyArg_ParseTuple(arg,"O",&argo)) return NULL;
if(PyInt_Check(argo))
{
/* 1 int arg */
signal=PyInt_AsLong(argo);
objs[0].ob=NULL;
objs[0].sigmask=signal;
listsize++;
}
else if(PyList_Check(argo))
{
/* 1 list arg */
int len=PyList_Size(argo);
if(len==0 || len>32)
{
PyErr_SetString(ValueError,"list size must be 1..32");
return NULL;
}
signal = 0;
for(i=0;i<len;i++)
{
PyObject *attr;
PyObject *item = PyList_GetItem(argo,i);
ULONG s;
if(PyInt_Check(item))
{
s = PyInt_AsLong(item);
objs[listsize].ob = NULL;
objs[listsize++].sigmask=s;
signal |= s;
}
else if(attr = PyObject_GetAttrString(item,"signal"))
{
ULONG s = PyInt_AsLong(attr);
if((s==-1) && PyErr_Occurred())
{
Py_DECREF(attr);
return NULL;
}
signal |= s;
objs[listsize].ob=item;
objs[listsize++].sigmask=s;
}
else return (PyObject*)PyErr_BadArgument();
}
}
else
{
/* other, try signal attribute */
PyObject *attr;
if(attr=PyObject_GetAttrString(argo,"signal"))
{
/* Found! */
signal = PyInt_AsLong(attr);
if((signal==-1) && PyErr_Occurred())
{
Py_DECREF(attr);
return NULL;
}
objs[0].ob = attr;
objs[0].sigmask = signal;
listsize++;
}
else return NULL;
}
if(doWait)
signal = Wait(signal);
else
signal = CheckSignal(signal);
if(result=PyList_New(0))
{
PyObject *tup;
for(i=0;i<listsize;i++)
{
if(objs[i].ob && (signal&objs[i].sigmask))
{
if(0!=PyList_Append(result,objs[i].ob))
{
Py_DECREF(result);
return NULL;
}
}
}
tup=Py_BuildValue("(iO)",signal,result);
Py_DECREF(result);
return tup;
}
else return NULL;
}
static PyObject *
Doslib_WaitSignal(PyObject *self, PyObject *arg)
{
return CheckOrWaitSignal(self,arg,TRUE);
}
static PyObject *
Doslib_CheckSignal(PyObject *self, PyObject *arg)
{
return CheckOrWaitSignal(self,arg,FALSE);
}
static PyObject *
Doslib_DateToStr(PyObject *self, PyObject *arg)
{
// (datestamp[,format=FORMAT_DOS,flags=0]) -> string
struct DateTime dt;
PyObject *ds_t;
int flags=0,format=FORMAT_DOS;
char day[32];
char date[32];
char time[32];
if(!PyArg_ParseTuple(arg,"O!|ii",&PyTuple_Type,&ds_t,&format,&flags)) return NULL;
if(!PyArg_ParseTuple(ds_t,"iii;invalid datestamp tuple",
&dt.dat_Stamp.ds_Days,&dt.dat_Stamp.ds_Minute,&dt.dat_Stamp.ds_Tick)) return NULL;
dt.dat_StrDay=day;
dt.dat_StrDate=date;
dt.dat_StrTime=time;
dt.dat_Flags=flags;
dt.dat_Format=format;
DateToStr(&dt);
return Py_BuildValue("(sss)",dt.dat_StrDay,dt.dat_StrDate,dt.dat_StrTime);
}
static PyObject *
Doslib_StrToDate(PyObject *self, PyObject *arg)
{
// (datestring[,timestring,format=FORMAT_DOS,flags=0]) -> datestamp
struct DateTime dt;
char *date;
char *time=NULL;
int flags=0,format=FORMAT_DOS;
if(!PyArg_ParseTuple(arg,"s|sii",&date,&time,&format,&flags)) return NULL;
memset(&dt,0,sizeof(dt));
dt.dat_StrDate=date;
dt.dat_StrTime=time;
dt.dat_Flags=flags;
dt.dat_Format=format;
StrToDate(&dt);
return Py_BuildValue("(iii)",dt.dat_Stamp.ds_Days,dt.dat_Stamp.ds_Minute,dt.dat_Stamp.ds_Tick);
}
static PyObject *
Doslib_CompareDates(PyObject *self, PyObject *arg) // (ds1, ds2) -> <0,0,>0
{
PyObject *ds_t1, *ds_t2;
struct DateStamp ds1,ds2;
if(!PyArg_ParseTuple(arg,"O!O!",
&PyTuple_Type,&ds_t1,&PyTuple_Type,&ds_t2)) return NULL;
if(!PyArg_ParseTuple(ds_t1,"iii;invalid datestamp tuple",&ds1.ds_Days,&ds1.ds_Minute,&ds1.ds_Tick)) return NULL;
if(!PyArg_ParseTuple(ds_t2,"iii;invalid datestamp tuple",&ds2.ds_Days,&ds2.ds_Minute,&ds2.ds_Tick)) return NULL;
return PyInt_FromLong(CompareDates(&ds1,&ds2));
}
static PyObject *
Doslib_DateStamp(PyObject *self, PyObject *arg) // () -> datestamp
{
struct DateStamp ds;
if(!PyArg_NoArgs(arg)) return NULL;
DateStamp(&ds);
return Py_BuildValue("(iii)",ds.ds_Days,ds.ds_Minute,ds.ds_Tick);
}
static PyObject *
Doslib_Fault(PyObject *self, PyObject *arg) // (errnum[, header]) -> string
{
int errnum;
char *header=NULL;
char buf[100];
if(!PyArg_ParseTuple(arg,"i|s",&errnum,&header)) return NULL;
Fault(errnum,header,buf,100);
return PyString_FromString(buf);
}
static PyObject *
Doslib_IoErr(PyObject *self, PyObject *arg) // () -> int
{
if(!PyArg_NoArgs(arg)) return NULL;
return PyInt_FromLong(IoErr());
}
static PyObject *
Doslib_SetIoErr(PyObject *self, PyObject *arg) // (int) -> int
{
int errnum;
if(!PyArg_ParseTuple(arg,"i",&errnum)) return NULL;
return PyInt_FromLong(SetIoErr(errnum));
}
static PyObject *
Doslib_IsFileSystem(PyObject *self, PyObject *arg) // (string) -> bool
{
char *name;
if(!PyArg_ParseTuple(arg,"s",&name)) return NULL;
return PyInt_FromLong(IsFileSystem(name));
}
static PyObject *
Doslib_Relabel(PyObject *self, PyObject *arg) // (oldvolname, newvolname)
{
char *old, *new;
if(!PyArg_ParseTuple(arg,"ss",&old,&new)) return NULL;
if(old[strlen(old)-1]!=':')
{
PyErr_SetString(ValueError,"volume name must end with :");
return NULL;
}
if(new[strlen(new)-1]==':')
{
PyErr_SetString(ValueError,"new name must not end with :");
return NULL;
}
return check_ok(Relabel(old,new));
}
static PyObject *
Doslib_SetProtection(PyObject *self, PyObject *arg) // (file,protbits) -> bool
{
char *name;
int pb;
if(!PyArg_ParseTuple(arg,"si",&name,&pb)) return NULL;
return check_ok(SetProtection(name,pb));
}
static PyObject *
Doslib_Examine(PyObject *self, PyObject *arg) // (filename) -> fib structure
{
char *name;
BPTR lock;
struct FileInfoBlock __aligned fib;
if(!PyArg_ParseTuple(arg,"s",&name)) return NULL;
if(lock=Lock(name,ACCESS_READ))
{
if(Examine(lock,&fib))
{
UnLock(lock);
return Py_BuildValue("(siiiii(iii)sii)",
fib.fib_FileName,
fib.fib_Size,
fib.fib_DirEntryType,
fib.fib_Protection,
fib.fib_DiskKey,
fib.fib_NumBlocks,
fib.fib_Date.ds_Days, fib.fib_Date.ds_Minute, fib.fib_Date.ds_Tick,
fib.fib_Comment,
fib.fib_OwnerUID,
fib.fib_OwnerGID);
/******************
return Py_BuildValue("(iisiiii(iii)sii)",
fib.fib_DiskKey,
fib.fib_DirEntryType,
fib.fib_FileName,
fib.fib_Protection,
fib.fib_EntryType,
fib.fib_Size,
fib.fib_NumBlocks,
fib.fib_Date.ds_Days, fib.fib_Date.ds_Minute, fib.fib_Date.ds_Tick,
fib.fib_Comment,
fib.fib_OwnerUID,
fib.fib_OwnerGID);
******************/
}
UnLock(lock);
}
return check_ok(FALSE);
}
static PyObject *
Doslib_SetComment(PyObject *self, PyObject *args)
{
char *path, *note;
if (!PyArg_ParseTuple(args, "ss", &path,¬e)) return NULL;
return check_ok(SetComment(path,note));
}
/* the offset between DateStamp() and time() epoch: */
#define TIME_OFFSET 252457200.0
static PyObject *
Doslib_DS2time(PyObject *self, PyObject *args)
{
struct DateStamp ds;
if(!PyArg_ParseTuple(args,"(iii)",&ds.ds_Days,&ds.ds_Minute,&ds.ds_Tick)) return NULL;
return PyFloat_FromDouble(
86400.0*ds.ds_Days + 60.0*ds.ds_Minute + ((double)ds.ds_Tick/50.0) + TIME_OFFSET
);
}
static PyObject *
Doslib_time2DS(PyObject *self, PyObject *args)
{
double t;
int days,minutes,ticks;
if(!PyArg_ParseTuple(args,"d",&t)) return NULL;
t -= TIME_OFFSET;
days = t / 86400.0;
t -= days*86400.0;
minutes = t / 60.0;
t -= minutes*60.0;
ticks = t*50.0;
return Py_BuildValue("(iii)",days,minutes,ticks);
}
/*** FUNCTIONS FROM THE MODULE ***/
static struct methodlist Doslib_global_methods[] = {
{"ReadArgs", Doslib_ReadArgs, 1},
{"WaitSignal", Doslib_WaitSignal, 1},
{"CheckSignal", Doslib_CheckSignal, 1},
{"CompareDates", Doslib_CompareDates, 1},
{"DateStamp", Doslib_DateStamp, 0},
{"DateToStr", Doslib_DateToStr, 1},
{"StrToDate", Doslib_StrToDate, 1},
{"Fault", Doslib_Fault, 1},
{"IoErr", Doslib_IoErr, 0},
{"SetIoErr", Doslib_SetIoErr, 1},
{"IsFileSystem", Doslib_IsFileSystem, 1},
{"Relabel", Doslib_Relabel, 1},
{"SetProtection", Doslib_SetProtection, 1},
{"SetComment", Doslib_SetComment, 1},
{"Examine", Doslib_Examine, 1},
{"DS2time", Doslib_DS2time, 1},
{"time2DS", Doslib_time2DS, 1},
{NULL, NULL} /* sentinel */
};
///
void
initdoslib Py_PROTO((void))
{
PyObject *m, *d;
m = Py_InitModule("doslib", Doslib_global_methods);
d = PyModule_GetDict(m);
/* Initialize error exception */
error = PyString_FromString("doslib.error");
if (error == NULL || PyDict_SetItemString(d, "error", error) != 0)
Py_FatalError("can't define doslib.error");
}